package com.ease.map.handler.feature.draw {
    import com.ease.map.Map;
    import com.ease.map.common.enum.LayerTypeEnum;
    import com.ease.map.common.enum.MapActionEnum;
    import com.ease.map.common.util.GMath;
    import com.ease.map.control.SelectFeaturesWindow;
    import com.ease.map.cursor.MoveFeatureCursor;
    import com.ease.map.events.EditEvent;
    import com.ease.map.events.MapEvent;
    import com.ease.map.feature.Feature;
    import com.ease.map.geometry.PointGeometry;
    import com.ease.map.geometry.PolygonGeometry;
    import com.ease.map.geometry.PolylineGeometry;
    import com.ease.map.geometry.basetype.Location;
    import com.ease.map.geometry.basetype.Pixel;
    import com.ease.map.handler.feature.draw.AbstractEditHandler;
    import com.ease.map.layer.FeatureLayer;
    import com.ease.map.style.PointStyle;
    
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    
    import mx.collections.ArrayCollection;
    import mx.managers.CursorManager;
    import mx.managers.PopUpManager;

    /**
     * 面编辑工具
     * */
    [ExcludeClass]
    public class EditPointHandler extends AbstractEditHandler {
        private var rotating:Boolean = false;
        private var startPoint:Location = null;
        private var endPoint:Location = null;
        private var endPiexl:Pixel = null;

        private var movePoint:PointGeometry;
        private var movePoints:ArrayCollection = new ArrayCollection();
        private var distance:Number;
        private var editFeatures:ArrayCollection;


        public function EditPointHandler(map:Map, handlername:String) {
            super(map, handlername);
        }

        override protected function registerListeners():void {
            if (this._drawContainer == null) {
                this._drawContainer = new FeatureLayer(-1, "editPoint");
                this._drawContainer.layerType = LayerTypeEnum.DYNAMICLAYER;
                this.map.addLayer(_drawContainer, true);
            }
            editFeature.buttonMode = false;
            map.operateMode = MapActionEnum.MAP_EDIT;
            this._clickHandler.active = true;
            this._clickHandler.doubleClick = this.mouseDblClick;
            this.map.addEventListener(EditEvent.VERTEX_MOUSE_OVER, vertexMouseOver);
            this.map.addEventListener(EditEvent.VERTEX_MOUSE_OUT, vertexMouseOut);
            this.map.addEventListener(MouseEvent.MOUSE_UP, mouseUp);
            this.map.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
			this.map.stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
        }

        override protected function unregisterListeners():void {
            this._drawContainer.clear();
            this.map.removeLayer(this._drawContainer);
            this._drawContainer = null;
            this._clickHandler.active = false;
            this.map.removeEventListener(EditEvent.VERTEX_MOUSE_OVER, vertexMouseOver);
            this.map.removeEventListener(EditEvent.VERTEX_MOUSE_OUT, vertexMouseOut);
            this.map.removeEventListener(MouseEvent.MOUSE_UP, mouseUp);
            this.map.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
            this.map.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
			this.map.stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
        }

        override protected function rotateAngleHandler():void {
            var fieldName:String = (editFeature.geoStyle as PointStyle).rotation;
            if ("" != fieldName && editFeature.fieldsMap.hasOwnProperty(fieldName)) {
                editFeature.fieldsMap[fieldName] = (Number)(rotateAngle.angleTxt.text) + (Number)(editFeature.fieldsMap[fieldName]);
            }
            editFeature.executeDrawing();
        }

        override protected function vertexMouseOver(event:EditEvent):void {
            if (MOVE_MODE) {
                isFeatureMove = true;
                _drawContainer.graphics.clear();
                editFeature.buttonMode = false;
                CursorManager.removeAllCursors();
                CursorManager.setCursor(MoveFeatureCursor);
            }
            if (ROTATE_MODE) {
                CursorManager.removeAllCursors();
            }
            if (MOVE_ASSOCIATED_MODE) {
                isFeatureMove = true;
                CursorManager.removeAllCursors();
                CursorManager.setCursor(MoveFeatureCursor);
            }
        }

        override protected function vertexMouseOut(event:EditEvent):void {
            if (MOVE_MODE || MOVE_ASSOCIATED_MODE) {
                if (!isFeatureMoving && isFeatureMove) {
                    isFeatureMove = false;
                    CursorManager.removeAllCursors();
                }
            }
            if (ROTATE_MODE && !rotating) {
                CursorManager.removeAllCursors();
            }
        }

        private function mouseDown(event:MouseEvent):void {
            if (MOVE_MODE || MOVE_ASSOCIATED_MODE) {
                isMouseDowning = false;
                var pixel:Pixel = new Pixel(map.mouseX, map.mouseY);
                var lonlat:Location = this.map.getLocationFromLayerPx(pixel);
                pointDown = new PointGeometry(lonlat.lon, lonlat.lat);
            }

        }

        private function mouseUp(event:MouseEvent):void {
            var pixel:Pixel = new Pixel(map.mouseX, map.mouseY);
            var lonlat:Location = this.map.getLocationFromLayerPx(pixel);

            pointUp = new PointGeometry(lonlat.lon, lonlat.lat);
            isMouseDowning = true;
            if (MOVE_MODE) {
                if (!pointUp.equals(pointDown)) //说明在拖动地图
                {

                }
                else {
                    //移动中再按下鼠标，结束移动
                    if (isFeatureMove && isFeatureMoving) {
                        //判断是否捕捉到了节点
                        if (snapReturn != null && snapReturn.snapPoint != null) {
                            (editFeature.geometry as PointGeometry).x = snapReturn.snapPoint.x;
                            (editFeature.geometry as PointGeometry).y = snapReturn.snapPoint.y;
                            if (this.snapClickCallback != null) {
//                                this.snapClickCallback(snapReturn.snapFeature, editAnchor.geoPoint);
								this.snapClickCallback(snapReturn.snapFeatures, editAnchor.geoPoint);
                            }
                            snapReturn = null;
                        }
                        else {
//                            var pixel:Pixel = new Pixel(this._drawContainer.mouseX, this._drawContainer.mouseY);
                            (editFeature.geometry as PointGeometry).x = this.map.getLocationFromLayerPx(moveEndPiexl).x;
                            (editFeature.geometry as PointGeometry).y = this.map.getLocationFromLayerPx(moveEndPiexl).y;
                        }
                        _drawContainer.graphics.clear();
                        CursorManager.removeAllCursors();
                        editFeature.executeDrawing();
                        isFeatureMoving = false;
                        isFeatureMove = false;
                        this.map.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
                    }
                    if (isFeatureMove && !isFeatureMoving) {
                        isFeatureMoving = true;
                        moveStartPiexl = new Pixel(_drawContainer.mouseX, _drawContainer.mouseY);
                        moveStartPoint = this.map.getLocationFromLayerPx(moveStartPiexl);
                        this.map.addEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
                    }

                }
            }
            if (MOVE_ASSOCIATED_MODE) {
                if (pointUp.equals(pointDown)) //说明在拖动地图
                {
                    if (isFeatureMove && isFeatureMoving) {
                        //第二次按下，说明关联移动结束
                        this.map.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
                        isFeatureMoving = false;
                        isFeatureMove = false;
                        CursorManager.removeAllCursors();
                    }
                    if (isFeatureMove && !isFeatureMoving) {
                        isFeatureMoving = true;
                        //关联移动
                        initAssociatedLayer();

                    }

                }
            }
            if (ROTATE_MODE) {
                if (!rotating) {
                    rotating = true; //第一次单击开始旋转
                    editFeature.buttonMode = false;
                    startPoint = new Location((editFeature.geometry as PointGeometry).x, (editFeature.geometry as PointGeometry).y);
                    this.map.addEventListener(MouseEvent.MOUSE_MOVE, mouseMove);

                }
                else {
                    rotating = false; //第二次单击 结束本次旋转
                    startPoint = null;
                    endPiexl = null;
                    endPoint = null;
                    editFeature.executeDrawing();
                    CursorManager.removeAllCursors();
                    this.map.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
                }
            }

        }

        private function initAssociatedLayer():void {
            //空间分析找出与其相连的，线、点设施、设置
            //找出每一个图层中的相关feature，增加动态图层
            movePoint = editFeature.geometry as PointGeometry;
            distance = map.resolution * snapTolerance;
            editFeatures = new ArrayCollection();
            for each (var layer:FeatureLayer in map.featureLayers) {
                if (layer.id != editFeature.layer.id) {
                    var result:ArrayCollection = layer.pointBufferAnalysis(movePoint, snapTolerance);
                    if (result.length > 0) {
                        editFeatures.addAll(result);
                    }
                }

            }
            if (moveFeatures && moveFeatures.length > 0) {
                this.map.addEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
            }
            else {
                var view:SelectFeaturesWindow = new SelectFeaturesWindow();
                view.dataProvider = editFeatures;
                view.closeFunction = onSelectFeaturesWindowClose;
                view.submitFunction = onSelectFeaturesWindowSubmit;
                PopUpManager.addPopUp(view, map, true);
                PopUpManager.centerPopUp(view);
                view.datagrid.selectedItems = editFeatures.toArray();
            }

        }

        private function onSelectFeaturesWindowSubmit(items:Array):void {
            //将移动的点也加入items
            items.push(editFeature);
            moveFeatures = new ArrayCollection(items);
            this.map.addEventListener(MouseEvent.MOUSE_MOVE, mouseMove);

            //找到所有编辑设施关联移动的点
            for each (var fea:Feature in moveFeatures) {
                fea.isLocked = true;
                if (fea.geometry is PointGeometry) {
                    movePoints.addItem(fea.geometry as PointGeometry);
                }
                else {
                    var line:PolylineGeometry;
                    if (fea.geometry is PolylineGeometry) {
                        line = fea.geometry as PolylineGeometry;
                    }
                    else if (fea.geometry is PolygonGeometry) {
                        line = (fea.geometry as PolygonGeometry).lineList.getItemAt(0) as PolylineGeometry;
                    }
                    var index:int = -1;
                    for (var j:int = 0; j < line.pointList.length; j++) {
                        if ((line.pointList.getItemAt(j) as PointGeometry).equals(movePoint) || (GMath.TwoPointDistance(movePoint, (line.pointList.getItemAt(j) as PointGeometry)) < distance)) {
                            index = j;
                            break;
                        }
                    }
                    if (index > -1) {
                        movePoints.addItem(line.pointList.getItemAt(index) as PointGeometry);
                    }
                }
            }
        }

        private function onSelectFeaturesWindowClose():void {
            //取消关联移动
            this.map.dispatchEvent(new EditEvent(EditEvent.GEOMETRY_EDITEND, editFeature, null, null));
            super.initialize();
        }

        private function mouseMove(event:MouseEvent):void {
            if (MOVE_MODE) {
                //移动设施
                if (isFeatureMoving && isMouseDowning) {
                    super.mouseMoveSnapHandler(event);
                    //清除已经画的临时增加点
                    _drawContainer.graphics.clear();
                    moveEndPiexl = new Pixel(this._drawContainer.mouseX, this._drawContainer.mouseY);
                    moveEndPoint = this.map.getLocationFromLayerPx(moveEndPiexl);
                    var offsetLocation:Location = new Location(moveEndPoint.x - moveStartPoint.x, moveEndPoint.y - moveStartPoint.y);
                    editFeature.geometry.offset(offsetLocation);
                    editFeature.executeDrawing();
                    moveStartPiexl = new Pixel(this._drawContainer.mouseX, this._drawContainer.mouseY);
                    moveStartPoint = this.map.getLocationFromLayerPx(moveStartPiexl);
                }
            }
            if (ROTATE_MODE && rotating) {
                //旋转点符号 计算两个点夹角
                _drawContainer.graphics.clear();
                endPiexl = new Pixel(this._drawContainer.mouseX, this._drawContainer.mouseY);
                endPoint = this.map.getLocationFromLayerPx(endPiexl);
                var fieldName:String = (editFeature.geoStyle as PointStyle).rotation;
                if ("" != fieldName && editFeature.fieldsMap.hasOwnProperty(fieldName)) {
                    editFeature.fieldsMap[fieldName] = GMath.lineAngle(startPoint.x, startPoint.y, endPoint.x, endPoint.y);
                }
                editFeature.executeDrawing();
            }
            if (MOVE_ASSOCIATED_MODE && isMouseDowning) {
                associatedMoving(event);
            }
        }

        /**
         * 关联移动相应mosemove事件，遍历feature，找出移动的节点，将当前鼠标坐标位置赋给此节点刷新feature。
         * */
        private function associatedMoving(event:MouseEvent):void {
            if (moveFeatures.length < 0) {
                return;
            }
//            super.mouseMoveSnapHandler(event);
            for each (var point:PointGeometry in movePoints) {
                point.x = map.getLocationFromLayerPx(new Pixel(editFeature.layer.mouseX, editFeature.layer.mouseY)).x;
                point.y = map.getLocationFromLayerPx(new Pixel(editFeature.layer.mouseX, editFeature.layer.mouseY)).y;
            }
            for each (var fea:Feature in moveFeatures) {
                fea.executeDrawing();
            }
        }

        private function updateZoom(evt:MapEvent):void {
            if (evt.zoomChanged) {
                if (editMode == 0 && DRAG_VERTICES_MODE) {
                    _startPoint1 = map.getLayerPxFromLocation(new Location(editingPoint1.x, editingPoint1.y));
                    _drawContainer.graphics.clear();
                    _drawContainer.graphics.lineStyle(2, 0x0000FF);
                    _drawContainer.graphics.moveTo(_drawContainer.mouseX, _drawContainer.mouseY);
                    _drawContainer.graphics.lineTo(_startPoint1.x, _startPoint1.y);
                    _drawContainer.graphics.endFill();
                }
                if (editMode == 1 && DRAG_VERTICES_MODE) {
                    _startPoint1 = map.getLayerPxFromLocation(new Location(editingPoint1.x, editingPoint1.y));
                    _startPoint2 = map.getLayerPxFromLocation(new Location(editingPoint2.x, editingPoint2.y));
                    _drawContainer.graphics.clear();
                    _drawContainer.graphics.lineStyle(2, 0x0000FF);
                    _drawContainer.graphics.moveTo(_drawContainer.mouseX, _drawContainer.mouseY);
                    _drawContainer.graphics.lineTo(_startPoint1.x, _startPoint1.y);
                    _drawContainer.graphics.moveTo(_drawContainer.mouseX, _drawContainer.mouseY);
                    _drawContainer.graphics.lineTo(_startPoint2.x, _startPoint2.y);
                    _drawContainer.graphics.endFill();

                }
            }
        }

    }
}